﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace HPPClientLibrary.DownLoad
{
    public class BufferPool
    {
        private Buffer[] _bufArray;

        private Stack<int> _unusedArrIndex;
        private Dictionary<int, bool> _unusedDict;

        private object _syncRoot = new object();

        public BufferPool(int arrayLength)
        {
            _bufArray = new Buffer[arrayLength];
            _unusedArrIndex = new Stack<int>();
            _unusedDict = new Dictionary<int, bool>();
            for (int i = 0; i < arrayLength; i++)
            {
                _bufArray[i] = new Buffer(i);
                _unusedArrIndex.Push(i);

                _unusedDict.Add(i, true);// true 表示未使用
            }


        }

        /// <summary>
        /// 从已分配的Buffer中获取一个Buffer
        /// </summary>
        /// <returns>获取到的Buffer</returns>
        public Buffer Alloc()
        {
            if (_unusedArrIndex.Count != 0)
            {
                lock (_syncRoot)
                {
                    if (_unusedArrIndex.Count != 0)
                    {
                        int index = _unusedArrIndex.Pop();
                        _unusedDict[index] = false;
                        return _bufArray[index];
                    }
                }
            }
            return null;
        }

        /// <summary>
        /// 把Buffer归还到BufferPool
        /// </summary>
        /// <param name="buffer">要归还的Buffer</param>
        /// <returns>是否归还成功</returns>
        public bool Dealloc(Buffer buffer)
        {
            if (_unusedDict.ContainsKey(buffer.Token) && !_unusedDict[buffer.Token])
            {
                lock (_syncRoot)
                {
                    if (_unusedDict.ContainsKey(buffer.Token) && !_unusedDict[buffer.Token])
                    {
                        _unusedDict[buffer.Token] = true;
                        _unusedArrIndex.Push(buffer.Token);
                        return true;
                    }
                }
            }
            return false;
        }

        /// <summary>
        /// 根据hash获得所有此hash的Buffer（用于某hash的文件完成下载，一次性写入缓存到磁盘）
        /// </summary>
        /// <param name="hash">作为key的hash</param>
        /// <returns>Buffer列表</returns>
        public List<Buffer> GetBufferList(string hash)
        {
            lock (_syncRoot)
            {
                List<Buffer> buffList = new List<Buffer>(_bufArray.Length - _unusedArrIndex.Count);
                for (int i = 0; i < _bufArray.Length; i++)
                {
                    if (_unusedDict.ContainsKey(i) && !_unusedDict[i] && _bufArray[i].Hash == hash && _bufArray[i].IsBufferFinish)
                    {
                        buffList.Add(_bufArray[i]);
                    }
                }
                return buffList;
            }
        }
    }
}
